package org.budo.warehouse.logic.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.budo.support.lang.util.MapUtil;
import org.budo.support.lang.util.StringUtil;
import org.budo.warehouse.logic.api.DataEntry;
import org.budo.warehouse.logic.api.DataEntryPojo.Column;
import org.budo.warehouse.logic.api.DataEntryPojo.Row;
import com.alibaba.fastjson.JSON;

/**
 * @author limingwei
 */
public class DataEntryUtil {
    public static boolean hasIsKeyColumn(DataEntry dataEntry, Integer rowIndex) {
        Integer columnCount = dataEntry.getColumnCount(rowIndex);

        for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
            Boolean columnIsKey = dataEntry.getColumnIsKey(rowIndex, columnIndex);
            if (columnIsKey) {
                return true;
            }
        }

        return false;
    }

    public static List<Map<String, Object>> rowsToSimplifyMaps(List<Row> rows) {
        if (null == rows) {
            return null;
        }

        List<Map<String, Object>> maps = new ArrayList<Map<String, Object>>();
        for (Row row : rows) {
            Map<String, Object> rowMap = simplify(row);
            maps.add(rowMap);
        }

        return maps;
    }

    public static String rowsToJson(List<Row> rows, Boolean simplify) {
        if (null == simplify || !simplify) {
            return JSON.toJSONString(rows);
        }

        List<Map<String, Object>> maps = rowsToSimplifyMaps(rows);
        return JSON.toJSONString(maps);
    }

    private static Map<String, Object> simplify(Row row) {
        List<Map<String, Object>> columns = simplify(row.getColumns());
        return MapUtil.stringObjectMap("columns", columns);
    }

    private static List<Map<String, Object>> simplify(List<Column> columns) {
        List<Map<String, Object>> columnMaps = new ArrayList<Map<String, Object>>();
        for (Column column : columns) {
            Map<String, Object> columnMap = simplify(column);
            if (null == columnMap || columnMap.isEmpty()) {
                continue;
            }

            columnMaps.add(columnMap);
        }
        return columnMaps;
    }

    private static Map<String, Object> simplify(Column column) {
        if (null == column) {
            return null;
        }

        Boolean isKey = column.getIsKey();
        Object valueBefore = column.getValueBefore();
        Object valueAfter = column.getValueAfter();
        if ((null == isKey || !isKey) // 非主键
                && StringUtil.equals(valueBefore, valueAfter)) { // 值未变
            return null;
        }

        // 非主键
        if (null == isKey || !isKey) {
            return MapUtil.stringObjectLinkedHashMap("name", column.getName(), //
                    "valueBefore", valueBefore, //
                    "valueAfter", valueAfter);
        }

        // 主键
        return MapUtil.stringObjectLinkedHashMap("name", column.getName(), //
                "isKey", isKey, //
                "valueBefore", valueBefore, //
                "valueAfter", valueAfter);
    }

    public static String rowsToJson(List<Row> rows) {
        return rowsToJson(rows, false);
    }

    public static List<Row> jsonToRows(String json) {
        return JSON.parseArray(json, Row.class);
    }

    public static List<Row> toRows(DataEntry dataEntry) {
        Integer rowCount = dataEntry.getRowCount();
        List<Row> _rows = new ArrayList<Row>(rowCount);
        for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
            _rows.add(new Row(dataEntry, rowIndex));
        }
        return _rows;
    }

    public static String toSimpleString(DataEntry dataEntry) {
        if (null == dataEntry) {
            return "dataEntry is null";
        }

        return "eventType=" + dataEntry.getEventType() //
                + ", sql=" + dataEntry.getSql() //
                + ", schemaName=" + dataEntry.getSchemaName() //
                + ", tableName=" + dataEntry.getTableName() //
                + ", rowCount=" + dataEntry.getRowCount();
    }

    public static Boolean isDropPartition(DataEntry dataEntry) {
        if (null == dataEntry || null == dataEntry.getSql()) {
            return false;
        }

        boolean contains = dataEntry.getSql().toUpperCase().contains("DROP PARTITION");
        return contains;
    }

    public static Boolean isDDL(DataEntry dataEntry) {
        if (null == dataEntry || null == dataEntry.getEventType()) {
            return false;
        }

        if ("CREATE".equalsIgnoreCase(dataEntry.getEventType()) // 建表
                || "ALTER".equalsIgnoreCase(dataEntry.getEventType()) // 改表
                || "RENAME".equalsIgnoreCase(dataEntry.getEventType()) // 表重命名
                || "TRUNCATE".equalsIgnoreCase(dataEntry.getEventType()) // 表清空
                || "ERASE".equalsIgnoreCase(dataEntry.getEventType())) { // 刪表
            return true;
        }

        return false;
    }

    public static Boolean isDML(DataEntry dataEntry) {
        if (null == dataEntry || null == dataEntry.getEventType()) {
            return false;
        }

        if ("INSERT".equalsIgnoreCase(dataEntry.getEventType()) //
                || "UPDATE".equalsIgnoreCase(dataEntry.getEventType()) //
                || "DELETE".equalsIgnoreCase(dataEntry.getEventType())) {
            return true;
        }

        return false;
    }
}